在 ASP.NET 使用 Redis 實作分散式快取
TLDR
- Windows 環境不建議使用微軟封存的 Redis 版本,建議使用 WSL 2、Docker 或 Memurai。
- 使用 Docker 部署 Redis 時,若遇到連線被拒,需調整
redis.conf中的bind與protected-mode設定。 - 單機環境建議優先使用
IMemoryCache,效能優於分散式快取。 IDistributedCache原生僅支援string存取,建議針對專案需求自行擴充 API。- 使用
IDistributedCache時,若資料可能異動,務必搭配AbsoluteExpiration或IChangeToken策略。
在 Windows 上安裝 Redis 的建議方案
由於 Redis 原生並未支援 Windows,在 Windows 環境開發時,請避免使用已停止維護的微軟封存版本。建議採取以下替代方案:
- WSL 2:官方推薦的 Linux 相容層安裝方式。
- Memurai:兼容 Redis 6.2 的 Windows 原生分支,適合開發與測試環境。
- Docker:透過官方 Image 部署,適合跨平台一致性需求。
使用 Docker 安裝 Redis 的注意事項
什麼情況下會遇到:當使用 Docker 部署 Redis 且外部應用程式無法連線至 Container 時。
若需自訂設定,請掛載 redis.conf 並透過 command 指定。若遇到連線被拒(Connection refused),請檢查並修改 redis.conf:
- 將
bind 127.0.0.1 -::1註解掉。 - 將
protected-mode yes改為protected-mode no。
TIP
bind 參數限制了允許連線的 IP,若設定為 127.0.0.1,則僅限本機連線。protected-mode 若設為 yes,則必須設定 bind 或 requirepass 密碼驗證。
在 ASP.NET Core 使用 MemoryCache
什麼情況下會遇到:當應用程式僅部署於單一伺服器,且對效能有極高要求時。
IMemoryCache 提供兩種過期策略:
- Absolute:絕對到期時間,時間一到即刪除。
- Sliding:滑動到期時間,若持續被讀取則會延長存活時間。
WARNING
若快取資料有異動可能,建議搭配 AbsoluteExpiration 或 IChangeToken 以確保資料一致性。
在 ASP.NET Core 使用 Redis 實作分散式快取
什麼情況下會遇到:當應用程式部署於多台伺服器(分散式架構),需要共享快取狀態時。
透過 Microsoft.Extensions.Caching.StackExchangeRedis 套件,可將 IDistributedCache 注入至專案中:
builder.Services.AddStackExchangeRedisCache(options => {
options.Configuration = builder.Configuration.GetConnectionString("Redis");
options.InstanceName = "SampleInstance";
});WARNING
若 App Server 僅有一台,使用 IMemoryCache 效能優於 IDistributedCache,因為後者涉及遠端網路存取。此外,IDistributedCache 原生僅支援 string 存取,建議針對複雜物件自行擴充 API。
在 ASP.NET Framework 使用 Redis
什麼情況下會遇到:維護舊版 .NET Framework (如 4.8) 專案時。
可直接使用 StackExchange.Redis 套件,並建議透過單例模式(Singleton)管理 ConnectionMultiplexer:
public sealed class RedisConnection {
private static readonly Lazy<RedisConnection> lazy = new Lazy<RedisConnection>(() => new RedisConnection());
private RedisConnection() {
ConnectionMultiplexer = ConnectionMultiplexer.Connect("127.0.0.1:6379");
}
public static RedisConnection Instance => lazy.Value;
public ConnectionMultiplexer ConnectionMultiplexer { get; }
}使用方式:
IDatabase db = RedisConnection.Instance.ConnectionMultiplexer.GetDatabase(0);
string cachedValue = await db.StringGetAsync("CacheKey");異動歷程
- 2022-11-02 初版文件建立。
